// src/composables/list/useListPage.ts
import { reactive, ref, toRaw } from "vue";
import { message } from "@/utils/message";
import { normalisePagination } from "@/api/_helpers";

interface PaginationOptions {
  pageSize?: number;
  pageSizes?: number[];
  layout?: string;
}

interface PaginationState {
  pageSize: number;
  currentPage: number;
  pageSizes: number[];
  total: number;
  align: string;
  background: boolean;
  size: string;
  layout: string;
}

interface ListResolved<RowType> {
  list: RowType[];
  total: number;
  pageSize: number;
  currentPage: number;
}

interface ListPageOptions<
  FormType,
  RowType,
  ParamsType = FormType & PaginationQuery,
  ResponseType = any
> {
  showSuccessMessages?: boolean;
  showErrorMessages?: boolean;
  successMessage?: string;
  errorMessage?: string;
  paramsAdapter?: (params: ParamsType) => any;
  responseAdapter?: (response: ResponseType) => ListResolved<RowType>;
}

interface PaginationQuery {
  page: number;
  page_size: number;
}

type ListApiService<FormType, ResponseType = any> = {
  fetch: (params: FormType & PaginationQuery) => Promise<ResponseType>;
};

const deepClone = <T>(value: T): T => {
  if (value === undefined) {
    return value;
  }
  if (typeof structuredClone === "function") {
    return structuredClone(value);
  }
  const serialized = JSON.stringify(value);
  return serialized ? (JSON.parse(serialized) as T) : value;
};

export function useListPage<
  FormType extends object,
  RowType = any,
  ResponseType = any
>(
  apiService: ListApiService<FormType, ResponseType>,
  defaultForm: FormType,
  paginationOptions: PaginationOptions = {},
  listPageOptions: ListPageOptions<
    FormType,
    RowType,
    FormType & PaginationQuery,
    ResponseType
  > = {}
) {
  const {
    showSuccessMessages = false,
    showErrorMessages = true,
    successMessage = "数据加载成功",
    errorMessage = "获取数据失败",
    paramsAdapter,
    responseAdapter
  } = listPageOptions;

  const defaultPagination: PaginationState = {
    pageSize: paginationOptions.pageSize || 10,
    pageSizes: paginationOptions.pageSizes || [10, 20, 50, 100],
    layout:
      paginationOptions.layout || "total, sizes, prev, pager, next, jumper",
    currentPage: 1,
    total: 0,
    align: "right",
    background: true,
    size: "default"
  };

  const initialFormSnapshot = deepClone({
    ...defaultForm,
    page: 1,
    page_size: defaultPagination.pageSize
  }) as FormType & PaginationQuery;

  const formState = reactive<FormType & PaginationQuery>({
    ...initialFormSnapshot
  });

  const pagination = reactive<PaginationState>({ ...defaultPagination });

  const dataList = ref<RowType[]>([]);
  const loading = ref(false);
  const multipleSelection = ref<RowType[]>([]);

  const resolveResponse = (response: ResponseType): ListResolved<RowType> => {
    if (responseAdapter) {
      return responseAdapter(response);
    }

    const rawResponse = (response as Record<string, any>) ?? {};
    const dataContainer = rawResponse.data ?? rawResponse;

    const rawList =
      dataContainer?.list ??
      dataContainer?.data ??
      dataContainer?.records ??
      dataContainer?.items ??
      [];

    let list: Array<RowType>;
    if (Array.isArray(rawList)) {
      list = rawList as Array<RowType>;
    } else if (Array.isArray(rawList?.data)) {
      list = rawList.data as Array<RowType>;
    } else if (Array.isArray(rawList?.records)) {
      list = rawList.records as Array<RowType>;
    } else if (Array.isArray(rawList?.items)) {
      list = rawList.items as Array<RowType>;
    } else {
      list = [];
    }

    const paginationSource =
      dataContainer?.pagination ??
      rawList?.pagination ??
      rawList?.meta ??
      rawList ??
      dataContainer;

    const paginationMeta = normalisePagination(
      paginationSource,
      formState.page,
      formState.page_size,
      list.length
    );

    return {
      list,
      total: paginationMeta.total,
      pageSize: paginationMeta.pageSize,
      currentPage: paginationMeta.currentPage
    };
  };

  const assignFormState = (source: FormType & PaginationQuery) => {
    Object.keys(source).forEach(key => {
      const value = (source as any)[key];
      (formState as any)[key] =
        value && typeof value === "object" ? deepClone(value) : value;
    });
  };

  const isEventObject = (value: unknown): value is Event => {
    return (
      typeof value === "object" &&
      value !== null &&
      "preventDefault" in value &&
      typeof (value as Event).preventDefault === "function"
    );
  };

  // 搜索
  const onSearch = async (additionalParams: Partial<FormType> | Event = {}) => {
    loading.value = true;
    try {
      const extraParams = isEventObject(additionalParams)
        ? {}
        : ((additionalParams ?? {}) as Partial<FormType>);

      const params = {
        ...(deepClone(toRaw(formState)) as FormType & PaginationQuery),
        ...extraParams,
        page: formState.page,
        page_size: formState.page_size
      };

      const requestParams = paramsAdapter ? paramsAdapter(params) : params;

      const response = await apiService.fetch(requestParams);
      const { list, total, pageSize, currentPage } = resolveResponse(response);

      pagination.total = total;
      pagination.pageSize = pageSize;
      pagination.currentPage = currentPage;
      dataList.value = list;

      formState.page = currentPage;
      formState.page_size = pageSize;

      if (showSuccessMessages) {
        message(successMessage, { type: "success" });
      }

      return response;
    } catch (error: any) {
      if (showErrorMessages) {
        message(`${errorMessage}: ${error?.message || "未知错误"}`, {
          type: "error"
        });
      }
      console.error(`${errorMessage}:`, error);
      throw error;
    } finally {
      loading.value = false;
    }
  };

  // 重置表单
  const resetForm = async () => {
    assignFormState(initialFormSnapshot);
    pagination.currentPage = 1;
    pagination.pageSize = initialFormSnapshot.page_size;
    await onSearch();
  };

  // 分页处理
  const handleSizeChange = async (val: number) => {
    const safeSize =
      Number.isFinite(val) && val > 0 ? val : initialFormSnapshot.page_size;
    pagination.pageSize = safeSize;
    formState.page_size = safeSize;
    await handlePageChange(1);
  };

  const handlePageChange = async (val: number) => {
    const safePage = Number.isFinite(val) && val > 0 ? val : 1;
    pagination.currentPage = safePage;
    formState.page = safePage;
    await onSearch();
  };

  // 多选处理
  const handleSelectionChange = (val: RowType[]) => {
    multipleSelection.value = Array.isArray(val) ? val : [];
  };

  return {
    formState,
    pagination,
    dataList,
    loading,
    multipleSelection,
    onSearch,
    resetForm,
    handleSizeChange,
    handlePageChange,
    handleSelectionChange
  };
}
